<template>
  <div class="my-cards">
    <div class="my-cards-list" :style="{height: tableHeight}">

      <el-row v-bind="rowProps">
        <el-col v-for="(item, index) in list"
                :key="index"
                v-bind="colProps"
                >
          <slot
            v-bind="{row: item, index, page:currentPage,pageSize:currentPageSize,total:currentTotal,columns:currentColumn}">
          </slot>
        </el-col>
      </el-row>

      <!-- 无数据提示 -->
      <div v-if="!this.currentLoading && !list.length" class="my-cards__empty">
        <slot name="empty">暂无数据</slot>
      </div>

    </div>
    <el-pagination ref="pager" class="pagination-container" v-if="pagination!==null && currentTotal"
                   v-bind="pagerProps"
                   :total="currentTotal"
                   :currentPage="currentPage"
                   @size-change="handlePageSizeChange"
                   @current-change="handlePageChange"
    >
    </el-pagination>
  </div>
</template>

<script>
import {getStyle} from 'element-ui/lib/utils/dom'

const defaultPagerProps = {
  background: true,
  layout: 'total, sizes, prev, pager, next, jumper'
}

export default {
  name: 'my-cards',
  cnName: '卡片展示',
  props: {
    loader: Function,
    pageSize: {
      type: Number,
      default: 20
    },
    // 数组总数
    total: {
      type: Number,
      default: 0
    },
    // 初始页码
    page: {
      type: Number,
      default: 1
    },
    // 分页组件其他配置
    pagination: {
      type: [Object, Boolean],
      default() {
        return {
          background: true,
          layout: 'total, sizes, prev, pager, next, jumper'
        }
      }
    },
    loading: Boolean,
    fit: {
      type: Boolean,
      default: true
    },
    rowProps: {
      type: Object,
      default() {
        return {
          gutter: 20
        }
      }
    },
    colProps: {
      type: Object,
      default() {
        return {
          xs: 12,
          sm: 8,
          md: 6,
          lg: 4,
          xl: 4
        }
      }
    }
  },
  data() {
    return {
      list: [],
      currentPage: this.page,
      currentTotal: this.total,
      currentPageSize: this.pageSize,
      currentLoading: this.loading,
      errorMessage: null,
      toolbarHeight: 0,
      pagerHeight: 0,
      // 响应式场景
      screens: {},
      currentColumn: 3,
    }
  },
  methods: {
    refresh(page) {
      this.currentPage = page || this.currentPage
      this.load()
    },
    load() {
      if (!this.loader) return
      this.currentLoading = true
      this.errorMessage = null

      this.loader(this.currentPage, this.currentPageSize).then(res => {
        this.list = res.list
        this.currentTotal = res.total || 0
        this.$emit('success', res)
      }).catch(e => {
        this.errorMessage = e;
        this.$emit('error', e)
      }).finally(() => {
        this.currentLoading = false
      })
    },
    handlePageSizeChange(size) {
      this.currentPage = 1;
      this.currentPageSize = size
      /**
       * 页大小变化时触发
       * @event size-change
       * @param {number} pageSize 页大小
       */
      this.$emit('size-change', size)
      this.load()
    },
    handlePageChange(page) {
      this.currentPage = page
      /**
       * 分页页码变化时触发
       * @event page-change
       * @param {number} page 页码
       * @param {number} pageSize 页大小
       */
      this.$emit('page-change', page, this.currentPageSize)
      this.load()
    },
    updateView() {
      if (this.$refs.toolbar) {
        const el = this.$refs.toolbar.$el
        const marginBottom = parseInt(getStyle(el, 'margin-bottom')) || 0
        this.toolbarHeight = el.getBoundingClientRect().height + marginBottom
      }
      if (this.$refs.pager) {
        const el = this.$refs.pager.$el
        const marginBottom = parseInt(getStyle(el, 'margin-bottom')) || 0
        const marginTop = parseInt(getStyle(el, 'margin-top')) || 0
        const pt = parseInt(getStyle(el, 'padding-top')) || 0
        const pb = parseInt(getStyle(el, 'padding-bottom')) || 0
        this.pagerHeight = el.getBoundingClientRect().height + marginBottom + marginTop + pt + pb
      }
    },

  },
  computed: {
    pagerProps() {
      return {
        ...defaultPagerProps,
        ...this.pagination,
        pageSize: this.pageSize,
        total: this.total,
        currentPage: this.page
      }
    },
    tableHeight() {
      if (!this.fit) return null
      return `calc(100% - ${this.toolbarHeight + this.pagerHeight}px)`
    }
  },
  watch: {
    list() {
      this.$nextTick(() => {
        this.updateView()
      })
    }
  },
  mounted() {
    this.updateView()
    this.load()
  }
}
</script>

<style lang="scss" scoped>
.my-cards {
  height: 100%;
  position: relative;

  &-list {
    position: relative;
    overflow-y: auto;
    border: 1px solid #dfe6ec;
    padding: 20px;
    box-sizing: border-box;
  }

  &__empty {
    text-align: center;
    padding: 20px;
    color: #8b8b8b;
  }
}
</style>
